﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Security.Principal;
using System.Text;

namespace Tiscs.Practices.Web.Services.Client
{
    /// <summary>
    /// 身份验证服务操作基类。
    /// </summary>
    /// <typeparam name="T">用户信息类的类型。</typeparam>
    public abstract class AuthenticationOperation<T> : AsyncOperationBase where T : IPrincipal
    {
        /// <summary>
        /// 构造方法。
        /// </summary>
        /// <param name="client">身份验证客户端实例。</param>
        /// <param name="userState">用户状态。</param>
        internal AuthenticationOperation(IAuthenticationServiceClient<T> client, object userState)
            : base(userState)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }
            Client = client;
            PropertyChanged += OnPropertyChanged;
        }

        /// <summary>
        /// 属性变化事件订阅。
        /// 用于当“Result”属性发生改变时，触发“User”属性变化事件。
        /// </summary>
        /// <param name="sender">事件源。</param>
        /// <param name="e">事件信息。</param>
        private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Result")
            {
                RaisePropertyChanged("User");
            }
        }

        /// <summary>
        /// 身份验证客户端实例。
        /// </summary>
        protected IAuthenticationServiceClient<T> Client
        {
            get;
            private set;
        }

        /// <summary>
        /// 是否支持取消操作。
        /// </summary>
        protected override bool SupportsCancellation
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// 当前用户。
        /// </summary>
        public T User
        {
            get
            {
                return (T)Result;
            }
        }

        /// <summary>
        /// 开始异步操作。
        /// </summary>
        internal void StartInternal()
        {
            base.Start();
        }
    }
}
